```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Spring AOP 全面解析 | 技术小馆</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', 'Noto Serif SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            background-color: #f8fafc;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #6e8efb 0%, #a777e3 100%);
        }
        .code-block {
            background-color: #2d2d2d;
            border-left: 4px solid #a777e3;
        }
        .advice-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
        }
        .section-divider {
            height: 1px;
            background: linear-gradient(90deg, rgba(167, 119, 227, 0) 0%, rgba(167, 119, 227, 0.5) 50%, rgba(167, 119, 227, 0) 100%);
        }
    </style>
</head>
<body class="text-gray-800 leading-relaxed">
    <!-- Hero Section -->
    <section class="hero-gradient text-white py-20 px-4 md:px-0">
        <div class="container mx-auto max-w-5xl text-center">
            <h1 class="text-4xl md:text-5xl font-bold mb-6">Spring AOP 全面解析</h1>
            <p class="text-xl md:text-2xl mb-8">掌握面向切面编程的核心概念与最佳实践</p>
            <div class="flex justify-center space-x-4">
                <div class="px-4 py-2 bg-white bg-opacity-20 rounded-full flex items-center">
                    <i class="fas fa-code mr-2"></i>
                    <span>Java</span>
                </div>
                <div class="px-4 py-2 bg-white bg-opacity-20 rounded-full flex items-center">
                    <i class="fas fa-project-diagram mr-2"></i>
                    <span>Spring框架</span>
                </div>
                <div class="px-4 py-2 bg-white bg-opacity-20 rounded-full flex items-center">
                    <i class="fas fa-magic mr-2"></i>
                    <span>切面编程</span>
                </div>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <main class="container mx-auto max-w-5xl px-4 md:px-0 py-12">
        <!-- Introduction -->
        <section class="mb-16">
            <p class="text-lg text-gray-700 leading-loose mb-8">
                在Spring AOP中，通知（Advice）是切面（Aspect）的一部分，用于在特定的连接点（Joinpoint）执行特定的操作。面向切面编程（AOP）是一种强大的编程范式，它允许开发者将横切关注点（如日志、事务、安全等）从业务逻辑中分离出来，实现更好的模块化和代码复用。
            </p>
            
            <!-- Mermaid Diagram -->
            <div class="bg-white rounded-xl shadow-lg p-6 mb-12">
                <div class="mermaid">
                    flowchart TD
                        A[客户端] --> B[目标对象]
                        B --> C{通知类型}
                        C --> D[前置通知]
                        C --> E[后置通知]
                        C --> F[异常通知]
                        C --> G[最终通知]
                        C --> H[环绕通知]
                        style A fill:#f5f5f5,stroke:#666
                        style B fill:#f5f5f5,stroke:#666
                        style C fill:#a777e3,stroke:#333,color:#fff
                        style D fill:#e2f0fd,stroke:#4a90e2
                        style E fill:#e4f7e8,stroke:#4caf50
                        style F fill:#ffebee,stroke:#f44336
                        style G fill:#fff3e0,stroke:#ff9800
                        style H fill:#f3e5f5,stroke:#9c27b0
                </div>
            </div>
        </section>

        <!-- Advice Types Section -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 text-gray-800 flex items-center">
                <i class="fas fa-list-check mr-4 text-purple-600"></i>
                通知类型详解
            </h2>
            
            <div class="grid md:grid-cols-2 gap-8">
                <!-- Before Advice -->
                <div class="advice-card bg-white rounded-xl shadow-lg p-6 transition-all duration-300">
                    <div class="flex items-center mb-4">
                        <div class="w-12 h-12 rounded-full bg-blue-100 flex items-center justify-center mr-4">
                            <i class="fas fa-arrow-right text-blue-600 text-xl"></i>
                        </div>
                        <h3 class="text-xl font-bold text-gray-800">前置通知</h3>
                    </div>
                    <p class="text-gray-700 mb-4">在目标方法执行之前执行，可以用于做一些准备工作或参数校验。</p>
                    <div class="text-sm text-blue-600 font-medium">
                        <i class="fas fa-code mr-1"></i> @Before
                    </div>
                </div>
                
                <!-- After Returning Advice -->
                <div class="advice-card bg-white rounded-xl shadow-lg p-6 transition-all duration-300">
                    <div class="flex items-center mb-4">
                        <div class="w-12 h-12 rounded-full bg-green-100 flex items-center justify-center mr-4">
                            <i class="fas fa-check text-green-600 text-xl"></i>
                        </div>
                        <h3 class="text-xl font-bold text-gray-800">后置通知</h3>
                    </div>
                    <p class="text-gray-700 mb-4">在目标方法成功执行之后执行，可以获取方法的返回值或做一些清理工作。</p>
                    <div class="text-sm text-green-600 font-medium">
                        <i class="fas fa-code mr-1"></i> @AfterReturning
                    </div>
                </div>
                
                <!-- After Throwing Advice -->
                <div class="advice-card bg-white rounded-xl shadow-lg p-6 transition-all duration-300">
                    <div class="flex items-center mb-4">
                        <div class="w-12 h-12 rounded-full bg-red-100 flex items-center justify-center mr-4">
                            <i class="fas fa-exclamation text-red-600 text-xl"></i>
                        </div>
                        <h3 class="text-xl font-bold text-gray-800">异常通知</h3>
                    </div>
                    <p class="text-gray-700 mb-4">在目标方法抛出异常时执行，可以用于处理异常或记录日志。</p>
                    <div class="text-sm text-red-600 font-medium">
                        <i class="fas fa-code mr-1"></i> @AfterThrowing
                    </div>
                </div>
                
                <!-- After Advice -->
                <div class="advice-card bg-white rounded-xl shadow-lg p-6 transition-all duration-300">
                    <div class="flex items-center mb-4">
                        <div class="w-12 h-12 rounded-full bg-orange-100 flex items-center justify-center mr-4">
                            <i class="fas fa-flag text-orange-600 text-xl"></i>
                        </div>
                        <h3 class="text-xl font-bold text-gray-800">最终通知</h3>
                    </div>
                    <p class="text-gray-700 mb-4">无论目标方法是否成功执行，都会在其后执行，通常用于做一些清理工作。</p>
                    <div class="text-sm text-orange-600 font-medium">
                        <i class="fas fa-code mr-1"></i> @After
                    </div>
                </div>
                
                <!-- Around Advice -->
                <div class="advice-card bg-white rounded-xl shadow-lg p-6 transition-all duration-300 md:col-span-2">
                    <div class="flex items-center mb-4">
                        <div class="w-12 h-12 rounded-full bg-purple-100 flex items-center justify-center mr-4">
                            <i class="fas fa-sync-alt text-purple-600 text-xl"></i>
                        </div>
                        <h3 class="text-xl font-bold text-gray-800">环绕通知</h3>
                    </div>
                    <p class="text-gray-700 mb-4">在目标方法执行前后都可以执行，可以完全控制目标方法的执行。这是功能最强大的通知类型。</p>
                    <div class="text-sm text-purple-600 font-medium">
                        <i class="fas fa-code mr-1"></i> @Around
                    </div>
                </div>
            </div>
        </section>

        <div class="section-divider my-12"></div>

        <!-- Implementation Section -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 text-gray-800 flex items-center">
                <i class="fas fa-cogs mr-4 text-purple-600"></i>
                Spring 实现 AOP
            </h2>
            
            <div class="mb-12">
                <h3 class="text-xl font-bold mb-4 text-gray-800">1. 创建切面类</h3>
                <p class="text-gray-700 mb-6">创建一个切面类，该类包含一个或多个通知方法。通常使用注解来标识切面类。</p>
                
                <div class="code-block rounded-lg overflow-hidden mb-6">
                    <div class="flex items-center bg-gray-800 px-4 py-2">
                        <div class="flex space-x-2 mr-4">
                            <div class="w-3 h-3 rounded-full bg-red-500"></div>
                            <div class="w-3 h-3 rounded-full bg-yellow-500"></div>
                            <div class="w-3 h-3 rounded-full bg-green-500"></div>
                        </div>
                        <span class="text-gray-400">MyAspect.java</span>
                    </div>
                    <pre class="text-gray-200 p-4 overflow-x-auto"><code>@Aspect
public class MyAspect {

    @Before("execution(* com.ts.MyService.doSomething(..))")
    public void beforeAdvice(JoinPoint joinPoint) {
        // 前置通知：在目标方法执行之前执行的逻辑
    }

    @AfterReturning(pointcut = "execution(* com.ts.MyService.doSomething(..))", returning = "result")
    public void afterReturningAdvice(JoinPoint joinPoint, Object result) {
        // 后置通知：在目标方法成功执行后执行的逻辑
    }

    @AfterThrowing(pointcut = "execution(* com.ts.MyService.doSomething(..))", throwing = "ex")
    public void afterThrowingAdvice(JoinPoint joinPoint, Throwable ex) {
        // 异常通知：在目标方法抛出异常时执行的逻辑
    }

    @After("execution(* com.ts.MyService.doSomething(..))")
    public void afterAdvice(JoinPoint joinPoint) {
        // 最终通知：在目标方法执行之后执行的逻辑
    }

    @Around("execution(* com.ts.MyService.doSomething(..))")
    public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        // 环绕通知：在目标方法执行前后都可以执行的逻辑
        Object result = null;
        try {
            // 在目标方法之前执行的逻辑
            result = proceedingJoinPoint.proceed(); // 执行目标方法
            // 在目标方法之后执行的逻辑
        } catch (Throwable t) {
            // 异常处理逻辑
            throw t;
        }
        return result;
    }
}</code></pre>
                </div>
            </div>
            
            <div class="mb-12">
                <h3 class="text-xl font-bold mb-4 text-gray-800">2. 在Spring配置文件中启用AOP</h3>
                <p class="text-gray-700 mb-6">配置切面类的引入并启用AOP功能。</p>
                
                <div class="code-block rounded-lg overflow-hidden mb-6">
                    <div class="flex items-center bg-gray-800 px-4 py-2">
                        <div class="flex space-x-2 mr-4">
                            <div class="w-3 h-3 rounded-full bg-red-500"></div>
                            <div class="w-3 h-3 rounded-full bg-yellow-500"></div>
                            <div class="w-3 h-3 rounded-full bg-green-500"></div>
                        </div>
                        <span class="text-gray-400">applicationContext.xml</span>
                    </div>
                    <pre class="text-gray-200 p-4 overflow-x-auto"><code>&lt;!-- 启用AOP --&gt;
&lt;aop:aspectj-autoproxy/&gt;

&lt;!-- 引入切面类 --&gt;
&lt;bean id="myAspect" class="com.ts.MyAspect"/&gt;</code></pre>
                </div>
            </div>
        </section>

        <div class="section-divider my-12"></div>

        <!-- Spring Boot Implementation -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 text-gray-800 flex items-center">
                <i class="fab fa-java mr-4 text-purple-600"></i>
                集成 Spring Boot 后的实现
            </h2>
            
            <div class="bg-blue-50 border-l-4 border-blue-500 p-4 mb-8">
                <div class="flex">
                    <div class="flex-shrink-0">
                        <i class="fas fa-info-circle text-blue-500 mt-1 mr-3"></i>
                    </div>
                    <div>
                        <p class="text-blue-800">Spring Boot 简化了AOP的配置，只需添加依赖并在启动类上添加注解即可。</p>
                    </div>
                </div>
            </div>
            
            <div class="mb-12">
                <h3 class="text-xl font-bold mb-4 text-gray-800">1. 添加AOP依赖</h3>
                <p class="text-gray-700 mb-6">在<code>pom.xml</code>中添加Spring AOP的依赖。</p>
                
                <div class="code-block rounded-lg overflow-hidden mb-6">
                    <div class="flex items-center bg-gray-800 px-4 py-2">
                        <div class="flex space-x-2 mr-4">
                            <div class="w-3 h-3 rounded-full bg-red-500"></div>
                            <div class="w-3 h-3 rounded-full bg-yellow-500"></div>
                            <div class="w-3 h-3 rounded-full bg-green-500"></div>
                        </div>
                        <span class="text-gray-400">pom.xml</span>
                    </div>
                    <pre class="text-gray-200 p-4 overflow-x-auto"><code>&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-aop&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
                </div>
            </div>
            
            <div class="mb-12">
                <h3 class="text-xl font-bold mb-4 text-gray-800">2. 创建切面类</h3>
                <p class="text-gray-700 mb-6">在项目中创建一个切面类，用于定义通知方法。</p>
                
                <div class="code-block rounded-lg overflow-hidden mb-6">
                    <div class="flex items-center bg-gray-800 px-4 py-2">
                        <div class="flex space-x-2 mr-4">
                            <div class="w-3 h-3 rounded-full bg-red-500"></div>
                            <div class="w-3 h-3 rounded-full bg-yellow-500"></div>
                            <div class="w-3 h-3 rounded-full bg-green-500"></div>
                        </div>
                        <span class="text-gray-400">MyAspect.java</span>
                    </div>
                    <pre class="text-gray-200 p-4 overflow-x-auto"><code>@Aspect
@Component
public class MyAspect {

    @Before("execution(* com.ts.MyService.doSomething(..))")
    public void beforeAdvice(JoinPoint joinPoint) {
        // 前置通知：在目标方法执行之前执行的逻辑
    }

    @AfterReturning(pointcut = "execution(* com.ts.MyService.doSomething(..))", returning = "result")
    public void afterReturningAdvice(JoinPoint joinPoint, Object result) {
        // 后置通知：在目标方法成功执行后执行的逻辑
    }

    @AfterThrowing(pointcut = "execution(* com.ts.MyService.doSomething(..))", throwing = "ex")
    public void afterThrowingAdvice(JoinPoint joinPoint, Throwable ex) {
        // 异常通知：在目标方法抛出异常时执行的逻辑
    }

    @After("execution(* com.ts.MyService.doSomething(..))")
    public void afterAdvice(JoinPoint joinPoint) {
        // 最终通知：在目标方法执行之后执行的逻辑
    }

    @Around("execution(* com.ts.MyService.doSomething(..))")
    public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        // 环绕通知：在目标方法执行前后都可以执行的逻辑
        Object result = null;
        try {
            // 在目标方法之前执行的逻辑
            result = proceedingJoinPoint.proceed(); // 执行目标方法
            // 在目标方法之后执行的逻辑
        } catch (Throwable t) {
            // 异常处理逻辑
            throw t;
        }
        return result;
    }
}</code></pre>
                </div>
            </div>
            
            <div class="mb-12">
                <h3 class="text-xl font-bold mb-4 text-gray-800">3. 启用AOP功能</h3>
                <p class="text-gray-700 mb-6">在Spring Boot的启动类上添加<code>@EnableAspectJAutoProxy</code>注解。</p>
                
                <div class="code-block rounded-lg overflow-hidden mb-6">
                    <div class="flex items-center bg-gray-800 px-4 py-2">
                        <div class="flex space-x-2 mr-4">
                            <div class="w-3 h-3 rounded-full bg-red-500"></div>
                            <div class="w-3 h-3 rounded-full bg-yellow-500"></div>
                            <div class="w-3 h-3 rounded-full bg-green-500"></div>
                        </div>
                        <span class="text-gray-400">MyApplication.java</span>
                    </div>
                    <pre class="text-gray-200 p-4 overflow-x-auto"><code>@SpringBootApplication
@EnableAspectJAutoProxy
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}</code></pre>
                </div>
            </div>
            
            <div class="mb-12">
                <h3 class="text-xl font-bold mb-4 text-gray-800">4. 编写目标服务类</h3>
                <p class="text-gray-700 mb-6">创建需要被AOP管理的目标服务类。</p>
                
                <div class="code-block rounded-lg overflow-hidden mb-6">
                    <div class="flex items-center bg-gray-800 px-4 py-2">
                        <div class="flex space-x-2 mr-4">
                            <div class="w-3 h-3 rounded-full bg-red-500"></div>
                            <div class="w-3 h-3 rounded-full bg-yellow-500"></div>
                            <div class="w-3 h-3 rounded-full bg-green-500"></div>
                        </div>
                        <span class="text-gray-400">MyService.java</span>
                    </div>
                    <pre class="text-gray-200 p-4 overflow-x-auto"><code>@Service
public class MyService {

    public void doSomething() {
        // 业务逻辑
    }
}</code></pre>
                </div>
            </div>
            
            <div class="bg-green-50 border-l-4 border-green-500 p-4">
                <div class="flex">
                    <div class="flex-shrink-0">
                        <i class="fas fa-check-circle text-green-500 mt-1 mr-3"></i>
                    </div>
                    <div>
                        <p class="text-green-800">完成以上步骤后，当<code>MyService</code>的<code>doSomething</code>方法被调用时，AOP切面中定义的通知方法将会按照相应的顺序执行。</p>
                    </div>
                </div>
            </div>
        </section>
    </main>

    <!-- Footer -->
    <footer class="bg-gray-900 text-gray-300 py-12">
        <div class="container mx-auto max-w-5xl px-4 md:px-0">
            <div class="flex flex-col items-center">
                <h3 class="text-xl font-medium text-white mb-4">技术小馆</h3>
                <a href="http://www.yuque.com/jtostring" class="text-gray-400 hover:text-white transition-colors duration-300">
                    <i class="fas fa-globe mr-2"></i>http://www.yuque.com/jtostring
                </a>
                <div class="mt-6 flex space-x-4">
                    <a href="#" class="w-8 h-8 rounded-full bg-gray-700 flex items-center justify-center hover:bg-purple-600 transition-colors duration-300">
                        <i class="fab fa-github"></i>
                    </a>
                    <a href="#" class="w-8 h-8 rounded-full bg-gray-700 flex items-center justify-center hover:bg-blue-500 transition-colors duration-300">
                        <i class="fab fa-twitter"></i>
                    </a>
                </div>
            </div>
        </div>
    </footer>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
        
        // 平滑滚动
        document.querySelectorAll('a[href^="#"]').forEach(anchor => {
            anchor.addEventListener('click', function (e) {
                e.preventDefault();
                document.querySelector(this.getAttribute('href')).scrollIntoView({
                    behavior: 'smooth'
                });
            });
        });
    </script>
</body>
</html>
```